import * as THREE from 'three';
import { BufferAttribute, BufferGeometry, Color, Geometry, Material, Mesh, Texture } from 'three';
import BaseThreeApp from '../BaseThreeApp';
import DebugInfo from '../DebugInfo';
import { VTKLoader } from 'three/examples/jsm/loaders/VTKLoader';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';

class _8_1GeometryParticle extends BaseThreeApp {
  public scene: THREE.Scene;
  public camera: THREE.Camera;
  public renderer: THREE.WebGLRenderer;
  public geos: (Geometry | BufferGeometry)[] = [];
  public mats: Material[] = [];
  public texs: Texture[] = [];
  public mesh: THREE.Points;

  start() {
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(
      60,
      this.clientWidth / this.clientHeight,
      0.1,
      1000
    );
    this.camera.position.z = 20;

    this.renderer = new THREE.WebGLRenderer({
      canvas: this.element,
    });

    const material = new THREE.PointsMaterial({
      color: 0xffffff,
      vertexColors: true,
      size: 0.1,
    });

    this.mats.push(material);

    this.renderer.setDrawingBufferSize(this.clientWidth, this.clientHeight, 1);

    const particleCount = 1000000;
    const width = 10;
    const positions = new Float32Array(particleCount * 3); // 使用点，只需要存储一个位置的xyz
    const colors = new Float32Array(particleCount * 3); // 存储RGB
    for (let i = 0; i < particleCount; i++) {
      const r1 = Math.random();
      const r2 = Math.random();
      const r3 = Math.random();
      const x = (r1 - 0.5) * width;
      const y = (r2 - 0.5) * width;
      const z = (r3 - 0.5) * width;
      positions[i] = x;
      positions[i + 1] = y;
      positions[i + 2] = z;
      colors[i] = r1;
      colors[i + 1] = r2;
      colors[i + 2] = r3;
    }
    function disposeArray() {
      this.array = null;
    }
    const geoBuf = new THREE.BufferGeometry();
    geoBuf.setAttribute(
      'position',
      new THREE.BufferAttribute(positions, 3, false).onUpload(disposeArray)
    );
    geoBuf.setAttribute(
      'color',
      new BufferAttribute(colors, 3, false).onUpload(disposeArray)
    );
    this.geos.push(geoBuf);

    const mesh = new THREE.Points(geoBuf, material);
    this.scene.add(mesh);
    this.mesh = mesh;

    this.isRunning = true;
    const animate = (time) => {
      if (!this.isRunning || this.element === null) {
        return;
      }
      this.mesh.rotation.set(time * 0.001, time * 0.001, 0);
      DebugInfo.Instance.begin();
      this.renderer.render(this.scene, this.camera);
      DebugInfo.Instance.end();
      requestAnimationFrame(animate);
    };
    animate(0);
  }

  onresize(e: UIEvent) {
    super.onresize(e);
    console.log('onresive');
    if (this.renderer) {
      this.renderer.setDrawingBufferSize(
        this.clientWidth,
        this.clientHeight,
        1
      );
      if (this.camera && this.camera instanceof THREE.PerspectiveCamera) {
        this.camera.aspect = this.clientWidth / this.clientHeight;
        this.camera.updateProjectionMatrix();
      }
    }
  }

  destory() {
    this.geos.forEach((v) => v.dispose());
    this.geos = [];
    this.mats.forEach((v) => v.dispose());
    this.mats = [];
    this.texs.forEach((v) => v.dispose());
    this.texs = [];
    super.destory();
  }
}

export default new _8_1GeometryParticle();
